import {
  Point,
  FabricImage,
  Group,
  BaseFabricObject,
  StaticCanvas,
} from 'fabric/node';
/**
 * Updates the fromObject function of a class to return a version that can restore old data
 * with values of originX and originY that are different from 'center', 'center'
 * Used to upgrade from fabric 6 to fabric 7
 * @param originalFn the original fromObject function of an object,
 * @param defaultOriginX optional default value for non exported originX,
 * @param defaultOriginY optional default value for non exported originY,
 * @returns a wrapped fromObject function for the object
 */
export const originUpdaterWrapper = (
  originalFn,
  defaultOriginX = 'left',
  defaultOriginY = 'top',
) =>
  async function (serializedObject, ...args) {
    // we default to left and top because those are defaults before deprecation
    const { originX = defaultOriginX, originY = defaultOriginY } =
      serializedObject;
    // and we do not want to pass those properties on the object anymore
    delete serializedObject.originX;
    delete serializedObject.originY;
    const originalObject = await originalFn.call(
      this,
      serializedObject,
      ...args,
    );
    const actualPosition = new Point(originalObject.left, originalObject.top);
    originalObject.setPositionByOrigin(actualPosition, originX, originY);
    return originalObject;
  };

// @ts-expect-error the _fromObject parameter could be instantiated differently
BaseFabricObject._fromObject = originUpdaterWrapper(
  BaseFabricObject._fromObject,
);
// FabricImage and Group do not use _fromObject
FabricImage.fromObject = originUpdaterWrapper(FabricImage.fromObject);
Group.fromObject = originUpdaterWrapper(Group.fromObject);

const json = {
  version: '4.5.1',
  objects: [
    {
      type: 'Path',
      version: '4.5.1',
      left: 213,
      top: 163,
      width: 180,
      height: 180,
      fill: '',
      stroke: 'red',
      strokeWidth: 2,
      path: [
        ['M', 0, 0],
        ['Q', 180, 0, 180, -101.25],
        ['Q', 180, -180, 90, -180],
        ['Q', 0, -180, 0, -112.5],
        ['Q', 0, -45, 78.75, -45],
        ['Q', 135, -45, 146.25, -90],
      ],
    },
    {
      type: 'Path',
      version: '4.5.1',
      left: 200,
      top: 6,
      width: 180,
      height: 180,
      fill: '',
      stroke: 'red',
      strokeWidth: 2,
      path: [
        ['M', 0, 0],
        ['Q', 180, 0, 180, -101.25],
        ['Q', 180, -180, 90, -180],
        ['Q', 0, -180, 0, -112.5],
        ['Q', 0, -45, 78.75, -45],
        ['Q', 135, -45, 146.25, -90],
      ],
    },
    {
      type: 'Path',
      version: '4.5.1',
      left: 18,
      top: 164,
      width: 180,
      height: 180,
      fill: '',
      stroke: 'red',
      strokeWidth: 2,
      path: [
        ['M', 0, 0],
        ['Q', 180, 0, 180, -101.25],
        ['Q', 180, -180, 90, -180],
        ['Q', 0, -180, 0, -112.5],
        ['Q', 0, -45, 78.75, -45],
        ['Q', 135, -45, 146.25, -90],
      ],
    },
    {
      type: 'Path',
      version: '4.5.1',
      left: 9,
      top: 14,
      width: 180,
      height: 180,
      fill: '',
      stroke: 'red',
      strokeWidth: 2,
      path: [
        ['M', 0, 0],
        ['Q', 180, 0, 180, -101.25],
        ['Q', 180, -180, 90, -180],
        ['Q', 0, -180, 0, -112.5],
        ['Q', 0, -45, 78.75, -45],
        ['Q', 135, -45, 146.25, -90],
      ],
    },
    {
      type: 'Text',
      version: '4.5.1',
      left: 10,
      top: 14,
      width: 180,
      height: 180,
      text: 'Text on a swirl textAlign right',
      fontSize: 28,
      textAlign: 'right',
      charSpacing: 50,
      path: {
        type: 'Path',
        version: '4.5.1',
        originX: 'left',
        originY: 'top',
        left: -0.5,
        top: -180.5,
        width: 180,
        height: 180,
        fill: 'rgb(0,0,0)',
        stroke: null,
        strokeWidth: 1,
        strokeDashArray: null,
        strokeLineCap: 'butt',
        strokeDashOffset: 0,
        strokeLineJoin: 'miter',
        strokeUniform: false,
        strokeMiterLimit: 4,
        scaleX: 1,
        scaleY: 1,
        angle: 0,
        flipX: false,
        flipY: false,
        opacity: 1,
        shadow: null,
        visible: false,
        backgroundColor: '',
        fillRule: 'nonzero',
        paintFirst: 'fill',
        globalCompositeOperation: 'source-over',
        skewX: 0,
        skewY: 0,
        path: [
          ['M', 0, 0],
          ['Q', 180, 0, 180, -101.25],
          ['Q', 180, -180, 90, -180],
          ['Q', 0, -180, 0, -112.5],
          ['Q', 0, -45, 78.75, -45],
          ['Q', 135, -45, 146.25, -90],
        ],
      },
      direction: 'ltr',
      styles: {},
    },
    {
      type: 'Text',
      version: '4.5.1',
      left: 15,
      top: 165,
      width: 180,
      height: 180,
      text: 'Text on a swirl textAlign left',
      fontSize: 28,
      charSpacing: 50,
      path: {
        type: 'Path',
        version: '4.5.1',
        originX: 'left',
        originY: 'top',
        left: -0.5,
        top: -180.5,
        width: 180,
        height: 180,
        fill: 'rgb(0,0,0)',
        stroke: null,
        strokeWidth: 1,
        strokeDashArray: null,
        strokeLineCap: 'butt',
        strokeDashOffset: 0,
        strokeLineJoin: 'miter',
        strokeUniform: false,
        strokeMiterLimit: 4,
        scaleX: 1,
        scaleY: 1,
        angle: 0,
        flipX: false,
        flipY: false,
        opacity: 1,
        shadow: null,
        visible: false,
        backgroundColor: '',
        fillRule: 'nonzero',
        paintFirst: 'fill',
        globalCompositeOperation: 'source-over',
        skewX: 0,
        skewY: 0,
        path: [
          ['M', 0, 0],
          ['Q', 180, 0, 180, -101.25],
          ['Q', 180, -180, 90, -180],
          ['Q', 0, -180, 0, -112.5],
          ['Q', 0, -45, 78.75, -45],
          ['Q', 135, -45, 146.25, -90],
        ],
      },
      direction: 'ltr',
      styles: {},
    },
    {
      type: 'Text',
      version: '4.5.1',
      left: 201,
      top: 9,
      width: 180,
      height: 180,
      text: 'Text on a swirl textAlign center',
      fontSize: 28,
      textAlign: 'center',
      charSpacing: 50,
      path: {
        type: 'Path',
        version: '4.5.1',
        originX: 'left',
        originY: 'top',
        left: -0.5,
        top: -180.5,
        width: 180,
        height: 180,
        fill: 'rgb(0,0,0)',
        stroke: null,
        strokeWidth: 1,
        strokeDashArray: null,
        strokeLineCap: 'butt',
        strokeDashOffset: 0,
        strokeLineJoin: 'miter',
        strokeUniform: false,
        strokeMiterLimit: 4,
        scaleX: 1,
        scaleY: 1,
        angle: 0,
        flipX: false,
        flipY: false,
        opacity: 1,
        shadow: null,
        visible: false,
        backgroundColor: '',
        fillRule: 'nonzero',
        paintFirst: 'fill',
        globalCompositeOperation: 'source-over',
        skewX: 0,
        skewY: 0,
        path: [
          ['M', 0, 0],
          ['Q', 180, 0, 180, -101.25],
          ['Q', 180, -180, 90, -180],
          ['Q', 0, -180, 0, -112.5],
          ['Q', 0, -45, 78.75, -45],
          ['Q', 135, -45, 146.25, -90],
        ],
      },
      direction: 'ltr',
      styles: {},
    },
    {
      type: 'Text',
      version: '4.5.1',
      left: 213,
      top: 164,
      width: 180,
      height: 180,
      text: 'full text to understand better a Text on a swirl textAlign',
      fontSize: 28,
      charSpacing: 50,
      path: {
        type: 'Path',
        version: '4.5.1',
        originX: 'left',
        originY: 'top',
        left: -0.5,
        top: -180.5,
        width: 180,
        height: 180,
        fill: 'rgb(0,0,0)',
        stroke: null,
        strokeWidth: 1,
        strokeDashArray: null,
        strokeLineCap: 'butt',
        strokeDashOffset: 0,
        strokeLineJoin: 'miter',
        strokeUniform: false,
        strokeMiterLimit: 4,
        scaleX: 1,
        scaleY: 1,
        angle: 0,
        flipX: false,
        flipY: false,
        opacity: 1,
        shadow: null,
        visible: false,
        backgroundColor: '',
        fillRule: 'nonzero',
        paintFirst: 'fill',
        globalCompositeOperation: 'source-over',
        skewX: 0,
        skewY: 0,
        path: [
          ['M', 0, 0],
          ['Q', 180, 0, 180, -101.25],
          ['Q', 180, -180, 90, -180],
          ['Q', 0, -180, 0, -112.5],
          ['Q', 0, -45, 78.75, -45],
          ['Q', 135, -45, 146.25, -90],
        ],
      },
      direction: 'ltr',
      styles: {},
    },
  ],
};

const canvas = new StaticCanvas();
await canvas.loadFromJSON(json);
canvas.includeDefaultValues = false;
console.log(JSON.stringify(canvas));
